package com.cinc.ebc.quote.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cinc.ebc.mm.entity.MmPurchaseRequisition;
import com.cinc.ebc.mm.entity.MmPurchaseRequisitionDetail;
import com.cinc.ebc.mm.enums.PurReqDetailStatusEnum;
import com.cinc.ebc.mm.enums.PurReqStatusEnum;
import com.cinc.ebc.mm.enums.PurReqTypeEnum;
import com.cinc.ebc.mm.mapper.MmPurchaseRequisitionMapper;
import com.cinc.ebc.mm.service.IMmPurchaseRequisitionService;
import com.cinc.ebc.quote.parts.entity.QuoteParts;
import com.cinc.ebc.quote.parts.mapper.QuotePartsMapper;
import com.cinc.ebc.quote.product.entity.QuoteProduct;
import com.cinc.ebc.quote.product.mapper.QuoteProductMapper;
import com.cinc.ebc.quote.project.entity.QuoteProject;
import com.cinc.ebc.quote.project.enums.ProjectStatusEnum;
import com.cinc.ebc.quote.project.mapper.QuoteProjectMapper;
import com.cinc.ebc.quote.project.service.IQuoteProjectService;
import com.cinc.ebc.sd.entity.SdContract;
import com.cinc.ebc.sd.entity.SdContractDetail;
import com.cinc.ebc.sd.enums.ContractStatusEnum;
import com.cinc.ebc.sd.enums.ContractTypeEnum;
import com.cinc.ebc.sd.enums.SaleTypeEnum;
import com.cinc.ebc.sd.mapper.SdContractMapper;
import com.cinc.ebc.sd.service.ISdContractService;
import com.cinc.mdm.modules.codeRule.service.IMdmCodeRuleService;
import com.cinc.mdm.modules.customer.entity.MdmCustomer;
import com.cinc.mdm.modules.customer.mapper.MdmCustomerMapper;
import com.cinc.mdm.modules.material.entity.MdmMaterial;
import com.cinc.mdm.modules.material.mapper.MdmMaterialMapper;
import org.jeecg.common.constant.GlobalConstants;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Description: 项目
 * @Author: jeecg-boot
 * @Date: 2022-08-20
 * @Version: V1.0
 */
@Service
public class QuoteProjectServiceImpl extends ServiceImpl<QuoteProjectMapper, QuoteProject> implements IQuoteProjectService {

    @Autowired
    private MmPurchaseRequisitionMapper mmPurchaseRequisitionMapper;

    @Autowired
    private IMmPurchaseRequisitionService mmPurchaseRequisitionService;

    @Autowired
    private QuotePartsMapper quotePartsMapper;

    @Autowired
    private IMdmCodeRuleService mdmCodeRuleService;

    @Autowired
    private MdmMaterialMapper mdmMaterialMapper;

    @Autowired
    private SdContractMapper sdContractMapper;

    @Autowired
    private QuoteProductMapper quoteProductMapper;

    @Autowired
    private MdmCustomerMapper mdmCustomerMapper;

    @Autowired
    private ISdContractService sdContractService;


    /**
     * 生成采购计划
     * @param quoteProject
     */
    @Transactional
    @Override
    public void generateReq(QuoteProject quoteProject) {
        QuoteProject quoteProjectData = baseMapper.selectById(quoteProject.getId());
        // 生成校验
        if(quoteProjectData == null){
            throw new RuntimeException("未找到项目数据");
        }
        if(!ProjectStatusEnum.CONFIRM.getCode().equals(quoteProjectData.getStatus())){
            throw new RuntimeException("项目当前状态不能生成采购计划");
        }
        LambdaQueryWrapper<MmPurchaseRequisition> reqQuery = new LambdaQueryWrapper<>();
        reqQuery.eq(MmPurchaseRequisition::getProjectId, quoteProjectData.getId());
        int reqCount = mmPurchaseRequisitionMapper.selectCount(reqQuery);
        if(reqCount > 0){
            throw new RuntimeException("项目已经维护了采购计划，不能再次生成");
        }
        LambdaQueryWrapper<QuoteParts> partsQuery = new LambdaQueryWrapper<>();
        partsQuery.eq(QuoteParts::getProjectId, quoteProjectData.getId());
        List<QuoteParts> quotePartsList = quotePartsMapper.selectList(partsQuery);
        if(oConvertUtils.listIsEmpty(quotePartsList)){
            throw new RuntimeException("项目零部件需求数据未找到，生成失败");
        }
        // 生成采购计划
        MmPurchaseRequisition mmPurchaseRequisition = new MmPurchaseRequisition();
        mmPurchaseRequisition.setId(UUIDGenerator.generate());
        mmPurchaseRequisition.setReqNo(mdmCodeRuleService.generateMmPurReqNo());
        mmPurchaseRequisition.setProjectId(quoteProjectData.getId());
        mmPurchaseRequisition.setApplyDate(new Date());
        mmPurchaseRequisition.setStatus(PurReqStatusEnum.NEW.getCode());
        mmPurchaseRequisition.setReqType(PurReqTypeEnum.TYPE01.getCode());
        LoginUser loginUser = JwtUtil.getLoginUser();
        mmPurchaseRequisition.setApplyEmpId(loginUser == null ? "" : loginUser.getUsername());
        mmPurchaseRequisition.setApplyDeptId(loginUser == null ? "" : loginUser.getOrgCode());
        List<MmPurchaseRequisitionDetail> requisitionDetailList = new ArrayList<>();
        int lintNo = 10;
        Date maxReqDate = new Date();
        for(QuoteParts parts : quotePartsList){
            MmPurchaseRequisitionDetail requisitionDetail = new MmPurchaseRequisitionDetail();
            requisitionDetail.setId(UUIDGenerator.generate());
            requisitionDetail.setLineNo(lintNo);
            requisitionDetail.setMaterialId(parts.getMaterialId());
            requisitionDetail.setMaterialNo(parts.getMaterialCode());
            requisitionDetail.setMaterialDesc(parts.getMaterialDesc());
            requisitionDetail.setUnit(parts.getUnit());
            requisitionDetail.setReqQty(parts.getQty());
            requisitionDetail.setPrice(parts.getSumPrice());
            requisitionDetail.setStatus(PurReqDetailStatusEnum.NEW.getCode());
            MdmMaterial material = mdmMaterialMapper.selectById(parts.getMaterialId());
            requisitionDetail.setBuyer(material.getMaterialBuyerId());
            int days = material.getDeliveryDays() == null ? 0 : material.getDeliveryDays().intValue();
            requisitionDetail.setReqDate(DateUtils.addDay(new Date(), days));
            requisitionDetailList.add(requisitionDetail);

            lintNo += 10;
            if(requisitionDetail.getReqDate().after(maxReqDate)){
                maxReqDate = requisitionDetail.getReqDate();
            }
        }
        mmPurchaseRequisition.setReqDate(maxReqDate);
        mmPurchaseRequisitionService.saveMain(mmPurchaseRequisition, requisitionDetailList);
        // 更新项目
        QuoteProject quoteProjectModify = new QuoteProject();
        quoteProjectModify.setId(quoteProject.getId());
        quoteProjectModify.setReqFlag(GlobalConstants.YES);
        baseMapper.updateById(quoteProjectModify);
        // 更新零部件需求
        quotePartsMapper.updatePartsHandleByProject(quoteProject.getId());
    }

    /**
     * 生成销售合同
     * @param quoteProject
     */
    @Transactional
    @Override
    public void generateSaleContract(QuoteProject quoteProject) {
        QuoteProject quoteProjectData = baseMapper.selectById(quoteProject.getId());
        if(quoteProjectData == null){
            throw new RuntimeException("未找到项目数据");
        }
        if(!ProjectStatusEnum.CONFIRM.getCode().equals(quoteProjectData.getStatus())){
            throw new RuntimeException("项目当前状态不能生成销售合同");
        }
        LambdaQueryWrapper<SdContract> contractQuery = new LambdaQueryWrapper<>();
        contractQuery.eq(SdContract::getProjectId, quoteProjectData.getId());
        int reqCount = sdContractMapper.selectCount(contractQuery);
        if(reqCount > 0){
            throw new RuntimeException("项目已经维护销售合同，不能再次生成");
        }
        LambdaQueryWrapper<QuoteProduct> quoteProductQuery = new LambdaQueryWrapper<>();
        quoteProductQuery.eq(QuoteProduct::getProjectId, quoteProjectData.getId());
        List<QuoteProduct> quoteProductList = quoteProductMapper.selectList(quoteProductQuery);
        if(oConvertUtils.listIsEmpty(quoteProductList)){
            throw new RuntimeException("项目产品数据未找到，生成失败");
        }
        // 生成销售合同
        SdContract sdContract = new SdContract();
        sdContract.setId(UUIDGenerator.generate());
        sdContract.setContractNo(mdmCodeRuleService.generateSdContractNo());
        sdContract.setProjectId(quoteProjectData.getId());
        sdContract.setCustomerId(quoteProjectData.getCustomerId());
        MdmCustomer mdmCustomer = mdmCustomerMapper.selectById(quoteProjectData.getCustomerId());
        sdContract.setCustomerName(mdmCustomer.getCustFullName());
        sdContract.setSaleType(SaleTypeEnum.TYPE01.getCode());
        sdContract.setContractType(ContractTypeEnum.TYPE01.getCode());
        sdContract.setCustomerSign(quoteProjectData.getCustomerId());
        sdContract.setStatus(ContractStatusEnum.TYPE01.getCode());

        List<SdContractDetail> sdContractDetailList = new ArrayList<>();
        int lintNo = 10;
        for(QuoteProduct product : quoteProductList){
            SdContractDetail contractDetail = new SdContractDetail();
            contractDetail.setId(UUIDGenerator.generate());
            contractDetail.setLineNo(lintNo);
            contractDetail.setMaterialId(product.getMaterialId());
            contractDetail.setMaterialNo(product.getMaterialNo());
            contractDetail.setMaterialDesc(product.getMaterialDesc());
            contractDetail.setUnit(product.getUnit());
            contractDetail.setQty(product.getQty());
            contractDetail.setUnitPrice(product.getUnitPrice());
            contractDetail.setSumPrice(product.getSumPrice());
            sdContractDetailList.add(contractDetail);

            lintNo += 10;
        }
        sdContractService.saveMain(sdContract, sdContractDetailList);
        // 更新项目
        QuoteProject quoteProjectModify = new QuoteProject();
        quoteProjectModify.setId(quoteProject.getId());
        quoteProjectModify.setSaleContractFlag(GlobalConstants.YES);
        baseMapper.updateById(quoteProjectModify);
    }

    @Override
    public void checkUse(String id) {
        int useCount = baseMapper.selectUseCount(id);
        if(useCount > 0){
            throw new RuntimeException("项目已经使用，不能删除");
        }
    }

    @Override
    public void checkUse(List<String> idList) {
        for(String id : idList){
            int useCount = baseMapper.selectUseCount(id);
            if(useCount > 0){
                throw new RuntimeException("项目已经使用，不能删除");
            }
        }
    }

    @Override
    public Map<String, Object> queryCountStatFp() {
        Map<String, Object> data = new HashMap<>();
        // 本年总数
        int sumCount = baseMapper.selectCountThisYear();
        data.put("sumCount", sumCount);
        // 本年各月数
        List<Map<String, Integer>> curMonthCountList = baseMapper.selectMonthCountThisYear();
        Map<String, Integer> curMonthMap = new HashMap<>();
        curMonthCountList.forEach(curMonthCount -> curMonthMap.put(curMonthCount.get("month")+"", curMonthCount.get("count")));
        List<Map<String, Object>> monthCountList = new ArrayList<>();
        for(int i =1; i<= 12; i++){
            Map<String, Object> monthCount = new HashMap<>();
            monthCount.put("x", i+"月");
            if(curMonthMap != null && curMonthMap.containsKey(i+"")){
                monthCount.put("y", curMonthMap.get(i+""));
            }else{
                monthCount.put("y", 0);
            }
            monthCountList.add(monthCount);
        }
        data.put("monthCountList", monthCountList);

        return data;
    }
}
